package com.wuseguang.springcloud.Filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wuseguang.springcloud.JdbcTemplate.BaseTemplate;
import com.wuseguang.springcloud.util.CodeUtil;
import com.wuseguang.springcloud.util.DateUtil;
import com.wuseguang.springcloud.util.JWTUtils;
import com.wuseguang.springcloud.util.Result;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.UnsupportedJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


@Component
@WebFilter(urlPatterns = "/console/*", filterName = "FilterUtil")
public class FilterUtil implements Filter {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private BaseTemplate baseTemplate;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    private String sql = "insert into `bancardlog` (`deviceid`, `url`,`param`, `result`, `time`, `opertime`) values(?,?,?,?,?,?);";

    private String bsql = "SELECT bancardlog  ints FROM bancard WHERE deviceid=?";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String token = request.getHeader("token");

        logger.info("uri = {}", request.getRequestURI());
        logger.info("token:" + token);
        //不需要拦截的请求
        String noIntercept[] = {"/tlogin", "/hystrix.stream", "/plogin", "/alogin","/areaLogin", "/check/checkContentAndPic","/admin/queryCarouselAll",
                "/quartz/haiweidaCron","/admin/queryApplyAll","/admin/queryLabel","/admin/queryAbout","/wxpay/notify","/actuator","/instances",
                "/haiweidaSynLog/inserthaiweidaSynLog"
        };

        //班牌接口
        if (request.getRequestURI().startsWith("/brands/")) {
            String requestURI = request.getRequestURI();//进来的url 路径
            long startTime = System.currentTimeMillis(); //获取开始时间
            String deviceid = request.getParameter("deviceid");//班牌设备号
            logger.info("brands startTime={},url = {},deviceid = {},threadName={}", startTime, requestURI, deviceid, Thread.currentThread().getName());
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            ResponseWrapper responseWrapper = new ResponseWrapper(response);//响应转换
            filterChain.doFilter(request, responseWrapper);
            String result = responseWrapper.getResponseData();//获取到响应的数据
            logger.info("brands result={},threadName={}", result, Thread.currentThread().getName());
            long endTime = System.currentTimeMillis(); //获取结束时间

            responseWrapper.inputResponse(response, result);//返回接口给客户端
            logger.info("brands  endTime={},url = {},deviceid = {},threadName={}", endTime, requestURI, deviceid, Thread.currentThread().getName());
            if (!StringUtils.isEmpty(deviceid) && !"/brands/queryBancardLog".equals(requestURI)) {//定时接口排除打印日志 和查看日志接口排除在外
                if ("/brands/updateHeartBeatTime".equals(requestURI)) {
                    if (baseTemplate.queryInteger(bsql, deviceid) == 0) {
                        return;
                    }
                }
                try {
                    Map<String, Object> map = new HashMap<>();
                    request.getParameterMap().forEach((key, value) -> map.put(key, value[0]));
                    baseTemplate.updateByParameter(sql, deviceid, requestURI, map.toString(), result, Double.valueOf(endTime - startTime) / 1000, DateUtil.time());//存储日志
                } catch (Exception e) {

                }
            }
            //判断是否是学生进入班牌中心
            if(request.getRequestURI().startsWith("/queryPersonalApplication")){
                //获取学生id
                Integer studentId = Integer.valueOf(request.getParameter("id"));
                //添加学生登录记录
                String sql = "INSERT INTO `area_login_times`(`user_id`, `type`, `login_time`,school_id) select id,3,now(),school_id from student where id = ?";
                baseTemplate.updateByParameter(sql,studentId);

                //查学生在班牌是否已近活跃
                sql = "select count(1) `count` from area_active where user_id = ? and type = 3 and TO_DAYS(add_time) = TO_DAYS(NOW())";
                Integer count = baseTemplate.queryCount(sql,studentId);
                //如果不大于0才添加数据
                if(count==0){
                    logger.info("不活跃");
                    //不活跃
                    sql = "INSERT INTO `area_active`(`user_id`, `type`, `add_time`, `active`,school_id) select id,3,now(),1,school_id from student where id = ?";
                    baseTemplate.queryCount(sql,studentId);
                }
            }
            return;
        }

        for (String filterUrl : noIntercept) {

            //判读是否是教师登录
            if(request.getRequestURI().startsWith("/tlogin")){
                //获取登录手机号码
                String phone = request.getParameter("phone");
                //添加学生登录记录
                String sql = "INSERT INTO `area_login_times`(`user_id`, `type`, `login_time`,school_id) select id,1,now(),school_id from teacher where phone = ?";
                baseTemplate.updateByParameter(sql,phone);

                //判断是否是家长登录
            }else if(request.getRequestURI().startsWith("/plogin")){
                ///获取登录手机号码
                String phone = request.getParameter("phone");
                //添加学生登录记录
                String sql = "INSERT INTO  `area_login_times`(`user_id`, `type`, `login_time`,school_id) select id,2,NOW(),school_id from student where `phone` =?";
                baseTemplate.updateByParameter(sql,phone);
            }

            if (request.getRequestURI().startsWith(filterUrl)) {
                //跳过token检测
                logger.info("Skip token detection = {}", token);
                filterChain.doFilter(request, servletResponse);
                return;
            }
        }

        //判断token不为空并且是教师端
        if (token != null && token.startsWith(JWTUtils.PREFIX_VALIDATION)) {
            String subject = null;

            try {
                //解析token的参数
                subject = Jwts.parser().setSigningKey(JWTUtils.SIGNINGKEY)
                        .parseClaimsJws(token.replace(JWTUtils.PREFIX_VALIDATION, "")).getBody().getSubject();
            } catch (ExpiredJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (UnsupportedJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                logger.info("token过期异常。。。");
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                return;
            }


            logger.info("This is the teacher side");
            String[] params = subject.split("-");

            if (params.length < 1) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }
            Map<String, Object> paramMap = new HashMap<String, Object>();

            //tkmobile表示登录的用户号
            paramMap.put("teacherPhone", params[0]);
            //tkteacherid表示老师ID
            paramMap.put("teacherId", params[1]);
            //教师名称
            paramMap.put("teacherName", params[2]);
            //t头像
            paramMap.put("teacherIcon", params[3]);
            //管理员
            paramMap.put("admin", params[4]);
            //学校id
            paramMap.put("schoolId", params[5]);
            //学期id
            paramMap.put("termId", params[6]);

            //添加自定义参数
            RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request);
            requestParameterWrapper.addParameters(paramMap);
            filterChain.doFilter(requestParameterWrapper, servletResponse);
            return;
        } else if (token != null && token.startsWith(JWTUtils.STUDENT_PREFIX_VALIDATION)) {
            logger.info("This is the parent");

            if (!request.getRequestURI().startsWith("/file/") && !request.getRequestURI().startsWith("/jurisdiction/") && !request.getRequestURI().startsWith("/getOfficialAccountOpenId")) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }

            String subject = null;

            try {
                //解析token的参数
                subject = Jwts.parser().setSigningKey(JWTUtils.SIGNINGKEY)
                        .parseClaimsJws(token.replace(JWTUtils.STUDENT_PREFIX_VALIDATION, "")).getBody().getSubject();
            } catch (ExpiredJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (UnsupportedJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                logger.info("token过期异常。。。");
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                return;
            }


            String[] params = subject.split("-");

            if (params.length < 1) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }
            Map<String, Object> paramMap = new HashMap<String, Object>();


            //parentId家长id
            paramMap.put("parentId", params[0]);
            //家长账号
            paramMap.put("parentPhone", params[1]);
            //家长名称
            paramMap.put("parentName", params[2]);
            //学校id
            paramMap.put("schoolId", params[3]);

            //添加自定义参数
            RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request);
            requestParameterWrapper.addParameters(paramMap);
            filterChain.doFilter(requestParameterWrapper, servletResponse);
            return;

        } else if (token != null && token.startsWith(JWTUtils.ADMIN_PREFIX_VALIDATION)) {
            logger.info("This is the admin");
            if (!request.getRequestURI().startsWith("/admin/")) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }
            String subject = null;

            try {
                //解析token的参数
                subject = Jwts.parser().setSigningKey(JWTUtils.SIGNINGKEY)
                        .parseClaimsJws(token.replace(JWTUtils.ADMIN_PREFIX_VALIDATION, "")).getBody().getSubject();
            } catch (ExpiredJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (UnsupportedJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                logger.info("token过期异常。。。");
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                return;
            }
            String[] params = subject.split("-");
            if (params.length < 1) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }
            Map<String, Object> paramMap = new HashMap<String, Object>();


            //管理员id
            paramMap.put("adminId", params[0]);
            //管理员账号
            paramMap.put("adminPhone", params[1]);
            //管理员名称
            paramMap.put("adminName", params[2]);
            //学校id
            paramMap.put("role", params[3]);
            //添加自定义参数
            RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request);
            requestParameterWrapper.addParameters(paramMap);
            filterChain.doFilter(requestParameterWrapper, servletResponse);
            return;
        }else if (token != null && token.startsWith(JWTUtils.AREA_PREFIX_VALIDATION)) {
            if (!request.getRequestURI().startsWith("/admin/")) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }
            String subject = null;

            try {
                //解析token的参数
                subject = Jwts.parser().setSigningKey(JWTUtils.SIGNINGKEY)
                        .parseClaimsJws(token.replace(JWTUtils.AREA_PREFIX_VALIDATION, "")).getBody().getSubject();
            } catch (ExpiredJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (UnsupportedJwtException e) {
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                e.printStackTrace();
                return;
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                logger.info("token过期异常。。。");
                onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
                return;
            }
            String[] params = subject.split("-");
            if (params.length < 1) {
                onAuthFailed(CodeUtil.LOGIN_FAILED, (HttpServletResponse) servletResponse);
                return;
            }
            Map<String, Object> paramMap = new HashMap<String, Object>();


            //id
            paramMap.put("areaPlatformId", params[0]);
            //区级手机号码
            paramMap.put("areaPlatformPhone", params[1]);
            //区级名称
            paramMap.put("areaName", params[2]);
            //区级简称
            paramMap.put("jianCheng", params[3]);
            //添加自定义参数
            RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request);
            requestParameterWrapper.addParameters(paramMap);
            filterChain.doFilter(requestParameterWrapper, servletResponse);
            return;
        }
        onAuthFailed(CodeUtil.LOG_IN_IN_THE_PAST, (HttpServletResponse) servletResponse);
        return;
    }


    private void onAuthFailed(CodeUtil CodeUtil, HttpServletResponse response) throws
            JsonProcessingException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        ObjectMapper mapper = new ObjectMapper();
        Result resultMsg = new Result(CodeUtil);
        response.getWriter().write(mapper.writeValueAsString(resultMsg));
    }

    @Override
    public void destroy() {

    }
}
